package org.linlinjava.litemall.admin.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.linlinjava.litemall.admin.beans.enums.MatApprovalStatusEnum;
import org.linlinjava.litemall.admin.errorcode.ErrorCodeConstants;
import org.linlinjava.litemall.admin.vo.hqmerchandise.*;
import org.linlinjava.litemall.admin.vo.merchandise.MerchandiseImportExcelVO;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static org.linlinjava.litemall.core.exception.util.ServiceExceptionUtil.exception;


/**
 * 管理商品服务
 *
 * @author yliyun
 * @date 2022/09/14
 */
@Service
@RequiredArgsConstructor
@Transactional
public class AdminHQMerchandiseService {

    private final LitemallMerchandiseService litemallMerchandiseService;

    private final LumiereHQMerchandiseImportLogService lumiereHQMerchandiseImportLogService;

    private final LumiereHQMerchandiseImportService lumiereHQMerchandiseImportService;

    private final LumiereMerchandiseService lumiereMerchandiseService;

    private final LumiereFormulaMaterialService lumiereFormulaMaterialService;

    private final LumiereMaterialClassificationService lumiereMaterialClassificationService;

    private final LumiereShopMaterialApprovalDetailService lumiereShopMaterialApprovalDetailService;

    private final LumiereShopMaterialApprovalReviewService lumiereShopMaterialApprovalReviewService;

    private final LitemallShopMerchandiseService litemallShopMerchandiseService;

    private final LitemallShopService litemallShopService;


    public ResponseUtil.Response hqList(HQListReqVO reqVO) {
        // 分页查询
        LambdaQueryWrapper<LitemallMerchandise> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(reqVO.getName()),LitemallMerchandise::getName,reqVO.getName());
        queryWrapper.like(StrUtil.isNotBlank(reqVO.getClassification()),LitemallMerchandise::getClassification,reqVO.getClassification());
        queryWrapper.orderByDesc(LitemallMerchandise::getAddTime);
        Page<LitemallMerchandise> page = litemallMerchandiseService.page(new Page(reqVO.getPage(), reqVO.getLimit()), queryWrapper);
        return ResponseUtil.okPage(page);
    }

    public ResponseUtil.Response hqImportLogList(HQListReqVO reqVO) {
        // 分页查询
        LambdaQueryWrapper<LumiereHQMerchandiseImportLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(reqVO.getName()),LumiereHQMerchandiseImportLog::getName,reqVO.getName());

        queryWrapper.orderByDesc(LumiereHQMerchandiseImportLog::getAddTime);
        IPage<LumiereHQMerchandiseImportLog> list = lumiereHQMerchandiseImportLogService.page(new Page<>(reqVO.getPage(),  reqVO.getLimit() ),queryWrapper);
        return ResponseUtil.okPage(list);
    }



    public ResponseUtil.Response hqImportList(HQListReqVO reqVO) {
        // 分页查询
        LambdaQueryWrapper<LumiereHQMerchandiseImport> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LumiereHQMerchandiseImport::getLogId,reqVO.getLogId());
        queryWrapper.like(StrUtil.isNotBlank(reqVO.getName()),LumiereHQMerchandiseImport::getName,reqVO.getName());

        queryWrapper.orderByDesc(LumiereHQMerchandiseImport::getAddTime);
        IPage<LumiereHQMerchandiseImport> list = lumiereHQMerchandiseImportService.page(new Page<>(reqVO.getPage(),  reqVO.getLimit()),queryWrapper);
        return ResponseUtil.okPage(list);
    }




    public Object hqImportMerchandiseList(MultipartFile file,List<MerchandiseImportExcelVO> importMerchandises,Integer adminId) {
        //记录
        LumiereHQMerchandiseImportLog importLog = new LumiereHQMerchandiseImportLog();
        importLog.setName(file.getOriginalFilename());
        importLog.setDeleted(false);
        importLog.setAddUserId(adminId);
        importLog.setUpdateUserId(adminId);
        lumiereHQMerchandiseImportLogService.save(importLog);
        //内容
        // 使用 Java Stream API 对列表进行过滤
        importMerchandises = importMerchandises.stream()
                .filter(importMerchandise ->
                        StrUtil.isNotEmpty(importMerchandise.getClassification()) &&
                                StrUtil.isNotEmpty(importMerchandise.getName()))
                .collect(Collectors.toList());
        // 1.1 参数校验
        if (CollUtil.isEmpty(importMerchandises)) {
            throw exception(ErrorCodeConstants.MERCHANDISE_IMPORT_LIST_IS_EMPTY);
        }

        List<LitemallMerchandise> litemallMerchandiseList = litemallMerchandiseService.selectList(Wrappers.lambdaQuery(LitemallMerchandise.class));

        List<LitemallMerchandise> merchandiseList = new ArrayList<>(importMerchandises.size());
        for (MerchandiseImportExcelVO importMerchandise : importMerchandises) {
            if(StrUtil.isEmpty(importMerchandise.getName())||StrUtil.isEmpty(importMerchandise.getClassification()))continue;
            //给门店添加库存,存在则改变数量，不存在则新增
            LitemallMerchandise merchandise = CollUtil.findOne(litemallMerchandiseList, item -> (item.getName()+item.getProperty()+item.getStandard()).toLowerCase().equals((importMerchandise.getName()+importMerchandise.getProperty()+importMerchandise.getStandard()).toLowerCase()));

            LumiereHQMerchandiseImport hqMerchandiseImport = new LumiereHQMerchandiseImport();
            hqMerchandiseImport.setLogId(importLog.getId());
            hqMerchandiseImport.setName(importMerchandise.getName());
            hqMerchandiseImport.setClassification(importMerchandise.getClassification());
            hqMerchandiseImport.setLabel(importMerchandise.getLabel());
            hqMerchandiseImport.setBrand(importMerchandise.getBrand());
            hqMerchandiseImport.setProperty(importMerchandise.getProperty());
            hqMerchandiseImport.setBasicUnit(importMerchandise.getBaseUnit());
            hqMerchandiseImport.setCheckUnit(importMerchandise.getCheckUnit());
            hqMerchandiseImport.setUnit(importMerchandise.getUnit());

            hqMerchandiseImport.setStandard(importMerchandise.getStandard());
            hqMerchandiseImport.setNumber(importMerchandise.getNumber());
            hqMerchandiseImport.setDeleted(false);
            lumiereHQMerchandiseImportService.save(hqMerchandiseImport);
            if(merchandise!=null){
                merchandise.setName(importMerchandise.getName());
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setStandard(importMerchandise.getStandard());
                merchandise.setProperty(importMerchandise.getProperty());
                merchandise.setNumber(merchandise.getNumber()+importMerchandise.getNumber());

                merchandise.setHqNumber(merchandise.getHqNumber()+importMerchandise.getNumber());
                lumiereMerchandiseService.updateById(merchandise);
            }else {
                merchandise = new LitemallMerchandise();
                merchandise.setMerchandiseSn(importMerchandise.getSerial());
                merchandise.setName(importMerchandise.getName());
                merchandise.setClassification(importMerchandise.getClassification());
                merchandise.setLabel(importMerchandise.getLabel());
                merchandise.setBrand(importMerchandise.getBrand());
                merchandise.setProperty(importMerchandise.getProperty());
                merchandise.setStandard(importMerchandise.getStandard());
                merchandise.setBasicUnit(importMerchandise.getBaseUnit());
                merchandise.setCheckUnit(importMerchandise.getCheckUnit());
                merchandise.setPurchasePrice(importMerchandise.getPurchasePrice());
                merchandise.setSellingPrice(importMerchandise.getSellingPrice());
                merchandise.setNumber(importMerchandise.getNumber());
                merchandise.setUnit(importMerchandise.getUnit());
                merchandise.setRatio(importMerchandise.getRatio());
                merchandise.setCheckRatio(importMerchandise.getCheckRatio());
                merchandise.setHqNumber(importMerchandise.getNumber());
                lumiereMerchandiseService.save(merchandise);
            }
            merchandiseList.add(merchandise);
        }

        //导入新的原料分类
        importMerchandisesClassification(importMerchandises);
        //导入配方原料表
        importFormulaMerchandises(merchandiseList);
        return ResponseUtil.ok(importMerchandises.size());
    }

    private void importMerchandisesClassification (List<MerchandiseImportExcelVO> importMerchandises){
        //新增原料分类
        for (MerchandiseImportExcelVO importMerchandise : importMerchandises) {
            List<LumiereMaterialClassification> materialClassificationList = lumiereMaterialClassificationService.list(Wrappers.lambdaQuery(LumiereMaterialClassification.class)
                    .isNull(LumiereMaterialClassification::getPid)
                    .eq(LumiereMaterialClassification::getClassificationName, importMerchandise.getClassification()));
            if(materialClassificationList.size()==0){
                //没有这种分类，新增
                lumiereMaterialClassificationService.save(new LumiereMaterialClassification()
                        .setClassificationName(importMerchandise.getClassification()).setNumber(1).setPid(null).setClassificationColour(getColor()));
            }
        }

    }

    private void importFormulaMerchandises(List<LitemallMerchandise> merchandiseList){

        CollUtil.filter(merchandiseList, (Filter<LitemallMerchandise>) merchandise -> {
            List<LumiereFormulaMaterial> formulaMaterials = lumiereFormulaMaterialService.list(Wrappers.lambdaQuery(LumiereFormulaMaterial.class).eq(LumiereFormulaMaterial::getMaterialName, merchandise.getName()));
            return formulaMaterials.size() == 0;
        });

        List<LumiereFormulaMaterial> formulaMaterialList = CollStreamUtil.toList(merchandiseList, merchandise -> {
            return new LumiereFormulaMaterial().setMaterialId(merchandise.getId())
                    .setMaterialName(merchandise.getName())
                    .setMaterialImg(merchandise.getPicUrl())
                    .setMaterialClassificationName(merchandise.getClassification()).setUnit(merchandise.getBasicUnit());
        });
        lumiereFormulaMaterialService.saveBatch(formulaMaterialList);
    }

    //随机生成颜色代码
    public String getColor(){
        //红色
        String red;
        //绿色
        String green;
        //蓝色
        String blue;
        //生成随机对象
        Random random = new Random();
        //生成红色颜色代码
        red = Integer.toHexString(random.nextInt(256)).toUpperCase();
        //生成绿色颜色代码
        green = Integer.toHexString(random.nextInt(256)).toUpperCase();
        //生成蓝色颜色代码
        blue = Integer.toHexString(random.nextInt(256)).toUpperCase();

        //判断红色代码的位数
        red = red.length()==1 ? "0" + red : red ;
        //判断绿色代码的位数
        green = green.length()==1 ? "0" + green : green ;
        //判断蓝色代码的位数
        blue = blue.length()==1 ? "0" + blue : blue ;
        //生成十六进制颜色值
        String color = "#"+red+green+blue;
        List<LumiereMaterialClassification> list = lumiereMaterialClassificationService.list(Wrappers.lambdaQuery(LumiereMaterialClassification.class)
                .eq(LumiereMaterialClassification::getClassificationColour, color));
        while (list.size()>0){
            color = getColor();
        }
        return color;
    }


    public ResponseUtil.Response shopReview(ShopReviewFormReqVO reqVO,Integer shopId,Integer adminId) {
        LitemallShop shop = litemallShopService.findById(shopId);
        LumiereShopMaterialApprovalReview shopMaterialApprovalReview = new LumiereShopMaterialApprovalReview();
        shopMaterialApprovalReview.setShopId(shopId);
        shopMaterialApprovalReview.setShopName(shop.getName());
        shopMaterialApprovalReview.setRemark(reqVO.getRemark());
        shopMaterialApprovalReview.setSerialNumber(reqVO.getSerialNumber());
        shopMaterialApprovalReview.setReview(MatApprovalStatusEnum.TYPE1.getType());
        shopMaterialApprovalReview.setAddUserId(adminId);
        shopMaterialApprovalReview.setUpdateUserId(adminId);
        shopMaterialApprovalReview.setDeleted(false);
        lumiereShopMaterialApprovalReviewService.save(shopMaterialApprovalReview);
        //详情
        List<ShopReviewFormReqVO.MaterialApproval> multipleMaterialSelectionList = reqVO.getMultipleMaterialSelectionList();
        if(CollUtil.isEmpty(multipleMaterialSelectionList)){
            throw exception(ErrorCodeConstants.MERCHANDISE_IMPORT_DATA_EMPTY_ERROR);
        }
        List<LumiereShopMaterialApprovalDetail> shopMaterialApprovalDetailList = new ArrayList<>();
        for (ShopReviewFormReqVO.MaterialApproval materialApproval : multipleMaterialSelectionList) {
            LumiereShopMaterialApprovalDetail shopMaterialApprovalDetail = BeanUtil.toBean(materialApproval,LumiereShopMaterialApprovalDetail.class);
            shopMaterialApprovalDetail.setId(null);
            shopMaterialApprovalDetail.setReviewId(shopMaterialApprovalReview.getId());
            shopMaterialApprovalDetail.setMaterialId(materialApproval.getId());
            shopMaterialApprovalDetail.setHqNumber(materialApproval.getHqNumber());
            shopMaterialApprovalDetail.setApplyNumber(shopMaterialApprovalDetail.getApplyNumber()==null?0:shopMaterialApprovalDetail.getApplyNumber());
            shopMaterialApprovalDetail.setDeleted(false);
            shopMaterialApprovalDetail.setAddTime(LocalDateTime.now());
            shopMaterialApprovalDetail.setUpdateTime(LocalDateTime.now());
            shopMaterialApprovalDetailList.add(shopMaterialApprovalDetail);
        }
        lumiereShopMaterialApprovalDetailService.saveBatch(shopMaterialApprovalDetailList);
        return ResponseUtil.ok(shopMaterialApprovalDetailList);
    }

    //减库存量
    private Boolean reduceMerchandiseStock(Integer id,Integer number){
        LitemallMerchandise merchandise = lumiereMerchandiseService.getById(id);
        merchandise.setHqNumber(merchandise.getHqNumber()-number);
        lumiereMerchandiseService.updateById(merchandise);
        return true;
    }

    public ResponseUtil.Response hQMaterialSummary() {
        List<LitemallMerchandise> merchandiseList = lumiereMerchandiseService.list();
        int totalImportedMaterialQuantity = 0;
        Set<String> materialClassifications = new HashSet<>();
        Set<String> materialTypes = new HashSet<>();
        if (merchandiseList != null) {
            for (LitemallMerchandise merchandise : merchandiseList) {
                // 统计导入原料总量
                totalImportedMaterialQuantity += merchandise.getHqNumber();
                // 统计原料总分类数
                materialClassifications.add(merchandise.getClassification());
                // 统计原料总类型数
                materialTypes.add(merchandise.getName());
            }
        }
        //导入总次数
        Long totalImportTimes = lumiereHQMerchandiseImportLogService.count();
        HQMaterialSummaryRespVO hqMaterialSummaryRespVO = new HQMaterialSummaryRespVO()
                .setTotalImportedMaterialQuantity(totalImportedMaterialQuantity)
                .setTotalMaterialCategories(materialClassifications.size())
                .setTotalImportTimes(totalImportTimes.intValue())
                .setTotalMaterialTypes(materialTypes.size());
        return ResponseUtil.ok(hqMaterialSummaryRespVO);
    }

    public ResponseUtil.Response hqMaterialApplicationReviewList(HQReviewListReqVO reqVO) {
        // 分页查询
        LambdaQueryWrapper<LumiereShopMaterialApprovalReview> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(reqVO.getSerialNumber()),LumiereShopMaterialApprovalReview::getSerialNumber,reqVO.getSerialNumber());
        queryWrapper.eq(reqVO.getShopId()!=null,LumiereShopMaterialApprovalReview::getShopId,reqVO.getShopId());
        queryWrapper.eq(reqVO.getReview()!=null,LumiereShopMaterialApprovalReview::getReview,reqVO.getReview());
        queryWrapper.orderByDesc(LumiereShopMaterialApprovalReview::getAddTime);
        IPage<LumiereShopMaterialApprovalReview> list = lumiereShopMaterialApprovalReviewService.page(new Page<>(reqVO.getPage(),  reqVO.getLimit()),queryWrapper);
        return ResponseUtil.okPage(list);
    }

    public ResponseUtil.Response hqMaterialApplicationReviewDetailList(HQReviewListReqVO reqVO) {
        // 分页查询
        LambdaQueryWrapper<LumiereShopMaterialApprovalDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LumiereShopMaterialApprovalDetail::getReviewId,reqVO.getReviewId());
        queryWrapper.orderByDesc(LumiereShopMaterialApprovalDetail::getAddTime);
        IPage<LumiereShopMaterialApprovalDetail> list = lumiereShopMaterialApprovalDetailService.page(new Page<>(reqVO.getPage(),  reqVO.getLimit()),queryWrapper);
        return ResponseUtil.okPage(list);
    }

    public ResponseUtil.Response hqReviewDelete(Integer id) {
        if(id!=null){
            lumiereShopMaterialApprovalReviewService.removeById(id);
        }
        return ResponseUtil.ok();
    }

    public ResponseUtil.Response hqMaterialReviewExecutor(Integer id, Integer status) {
        if(id==null){return ResponseUtil.ok();}
        LumiereShopMaterialApprovalReview materialApprovalReview = lumiereShopMaterialApprovalReviewService.getById(id);

        List<LitemallMerchandise> merchandiseList = new ArrayList<>();
        if(status==MatApprovalStatusEnum.TYPE2.getType()){
            List<String> hqMaterialInsufficient = new ArrayList<>();

            //执行库存扣减，门店原料入库，增加
            List<LumiereShopMaterialApprovalDetail> materialApprovalDetails = lumiereShopMaterialApprovalDetailService.list(Wrappers.lambdaQuery(LumiereShopMaterialApprovalDetail.class)
                    .eq(LumiereShopMaterialApprovalDetail::getReviewId, id));
            for (LumiereShopMaterialApprovalDetail materialApprovalDetail : materialApprovalDetails) {
                //扣减库存
                LitemallMerchandise merchandise = lumiereMerchandiseService.getById(materialApprovalDetail.getMaterialId());

                if(merchandise.getHqNumber()-materialApprovalDetail.getApplyNumber()<0){
                    hqMaterialInsufficient.add(merchandise.getName());
                }
                merchandise.setHqNumber(merchandise.getHqNumber()-materialApprovalDetail.getApplyNumber());
                merchandiseList.add(merchandise);

                //给门店添加库存,存在则改变数量，不存在则新增
                LitemallShopMerchandise shopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandise.getId(), materialApprovalReview.getShopId());

                if(shopMerchandise != null){
                    Double number = shopMerchandise.getNumber()+materialApprovalDetail.getApplyNumber()*merchandise.getRatio();//计算入库的数量(盘点单位)
                    Double basicNumber = number*merchandise.getCheckRatio();//计算入库的数量(基本单位)
                    shopMerchandise.setNumber(number);
                    shopMerchandise.setBasicNumber(basicNumber);
                    shopMerchandise.setProperty(merchandise.getProperty());
                    shopMerchandise.setStockNumber(shopMerchandise.getStockNumber()+materialApprovalDetail.getApplyNumber());
                    litemallShopMerchandiseService.updateById(shopMerchandise);
                }else{
                    Double number = materialApprovalDetail.getApplyNumber()*merchandise.getRatio().doubleValue();//计算入库的数量(盘点单位)
                    Double basicNumber = number*merchandise.getCheckRatio();//计算入库的数量(基本单位)
                    shopMerchandise = new LitemallShopMerchandise();
                    shopMerchandise.setMerchandiseId(merchandise.getId());
                    shopMerchandise.setNumber(number);
                    shopMerchandise.setBasicNumber(basicNumber);
                    shopMerchandise.setSellPrice(merchandise.getSellingPrice());
                    shopMerchandise.setShopId(materialApprovalReview.getShopId());
                    shopMerchandise.setProperty(merchandise.getProperty());
                    shopMerchandise.setStockNumber(materialApprovalDetail.getApplyNumber());
                    shopMerchandise.setDeleted(false);
                    litemallShopMerchandiseService.create(shopMerchandise);
                }
            }
            if(hqMaterialInsufficient.size()>0){
                throw exception(ErrorCodeConstants.MERCHANDISE_HQ_MATERIAL_INSUFFICIENT_ERROR, hqMaterialInsufficient);
            }
            lumiereMerchandiseService.updateBatchById(merchandiseList);

        }
        //更新审核状态
        materialApprovalReview.setReview(status);
        lumiereShopMaterialApprovalReviewService.updateById(materialApprovalReview);
        return ResponseUtil.ok(status);
    }
}
